﻿using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Trentacular.Office.Server.Search.FacetedSearch;
using Trentacular.Office.Server.Web.UI.WebParts;
using Trentacular.SharePoint.Web.UI;
using Trentacular.SharePoint.Web.UI.WebControls;

namespace Trentacular.Office.Server.Web.UI.UserControls
{
    public partial class SearchFacets : BaseSPUserControl
    {
        public new FacetedSearchWebPart Parent
        {
            get { return (FacetedSearchWebPart)base.Parent; }
        }

        protected void Page_PreRender(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                ASB_TQS_AndQ_tb.Value = Request.QueryString["k"];
            }
            else
            {
                FacetedSearchContext.SaveToViewState(this.ViewState);
            }

            // Save all Advanced Search fields locally
            foreach (var formKey in Request.Form.AllKeys)
            {
                if (formKey.Contains("ASB_TQS_AndQ_tb"))
                    SyncAdvancedSearchKeywordField(formKey, ASB_TQS_AndQ_tb);
                else if (formKey.Contains("ASB_TQS_PhraseQ_tb"))
                    SyncAdvancedSearchKeywordField(formKey, ASB_TQS_PhraseQ_tb);
                else if (formKey.Contains("ASB_TQS_OrQ_tb"))
                    SyncAdvancedSearchKeywordField(formKey, ASB_TQS_OrQ_tb);
                else if (formKey.Contains("ASB_TQS_NotQ_tb"))
                    SyncAdvancedSearchKeywordField(formKey, ASB_TQS_NotQ_tb);
                else if (formKey.Contains("ASB_SS_scb_") ||
                    formKey.Contains("ASB_SS_lcb_") ||
                    formKey.Contains("ASB_PS_"))
                {
                    var value = Request.Form[formKey] ?? string.Empty;
                    phScopeHiddenFields.Controls.Add(
                        new LiteralControl(
                            string.Format(
                                @"<input id=""{0}"" name=""{0}"" type=""hidden"" value=""{1}"" />",
                                formKey,
                                HttpUtility.HtmlAttributeEncode(value)
                                )
                            )
                        );
                }
                else if (!IsPostBack &&
                    formKey.Equals("ASB_ResType_Query") &&
                    string.IsNullOrEmpty(advSearchResTypeQueryHiddenField.Value))
                {
                    // Save off the ASB_ResType_Query parameter to a different hidden field
                    // since we will be overwriting it.
                    var value = Request.Form[formKey] ?? string.Empty;
                    advSearchResTypeQueryHiddenField.Value = value;
                }
            }

            // Build Debug Panel
            debugPanel.Visible = Parent.EnableDebugPanel;
            if (Parent.EnableDebugPanel)
            {
                var queryRetriever = FacetedSearcher.GetQueryRetriever(Context);
                litQueryText.Text = queryRetriever.QueryText;
            }
        }

        private void SyncAdvancedSearchKeywordField(string formKey, HiddenField hiddenField)
        {
            var value = (Request.Form[formKey] ?? string.Empty).Trim();
            if (value.Length > 0)
            {
                hiddenField.Value = value;
            }
        }

        private FacetedSearchContext _facetedSearchContext;
        protected FacetedSearchContext FacetedSearchContext
        {
            get
            {
                if (_facetedSearchContext == null)
                    _facetedSearchContext = InitializeFacetedSearchContext();
                return _facetedSearchContext;
            }
        }

        private FacetedSearchContext InitializeFacetedSearchContext()
        {
            // First load from ViewState
            var facetedSearchContext = FacetedSearchContext.LoadFromViewState(this.ViewState);

            // Now add / remove newly clicked facet if present
            var targetFacet = targetFacetHiddenField.Value;
            var targetAction = targetActionHiddenField.Value;
            if (!string.IsNullOrEmpty(targetAction) && !string.IsNullOrEmpty(targetFacet))
            {
                try
                {
                    var addActiveFacet = targetAction.Equals("Add", StringComparison.InvariantCultureIgnoreCase);
                    var parts = targetFacet.Split(new[] { '_' }, 2);
                    var configurationID = new Guid(parts[0]);
                    var key = parts[1];
                    if (addActiveFacet)
                        facetedSearchContext.AddActiveFacet(configurationID, key);
                    else
                        facetedSearchContext.RemoveActiveFacet(configurationID, key);
                }
                catch { /* Ignore Exceptions */ }
            }

            // Reset the Target Hidden Fields
            targetFacetHiddenField.Value = null;
            targetActionHiddenField.Value = null;

            return facetedSearchContext;
        }

        #region Repeater Container DataItem Holder Fields

        protected FacetGroup CurrentFacetGroup;
        protected string SetCurrentFacetGroup(object facetGroup)
        {
            CurrentFacetGroup = (FacetGroup)facetGroup;
            return null;
        }

        protected Facet CurrentFacet;
        protected string SetCurrentFacet(object facet)
        {
            CurrentFacet = (Facet)facet;
            return null;
        }

        #endregion

        protected void GetFacetGroups(DelegateSelectArguments args)
        {
            var facetedSearcher = new FacetedSearcher(FacetedSearchContext, Parent.FacetProviderConfigurations)
            {
                FacetResultsRowLimit = Parent.FacetResultsRowLimit
            };

            try
            {
                args.Results = facetedSearcher.Execute();
            }
            catch (Exception e)
            {
                //Log.Error("Error generating search facets", e);
                errorMessages.Visible = true;
                errorMessages.Controls.Add(new LiteralControl(e.Message));
            }
        }
    }
}
